local screenWidth, screenHeight = guiGetScreenSize()
local cursorLayers = 0
local canMeChangeWeapons = true

local blips = {}
local data = {}

local classColor
local winsColor

local classNameString
local winsString
local startingString
local countString
local roundTimeString 
local loadingRoundString
local teamStrings = {}
local outString

local fps = 0
local fpsTime = getTickCount()

-- UNVERSAL FUNCTIONS
function cursorShow(bool)
	if(bool) then 
		if(cursorLayers == 0) then
			showCursor(true)
		end
		cursorLayers = cursorLayers + 1 
	else
		if(cursorLayers - 1 == 0) then
			showCursor(false)
		end
		cursorLayers = cursorLayers - 1 
	end
end

function seconds(count)
	last = count % 10
	if last == 1 then return "секунду" end
	if last >= 2 and last <= 4 then return "секунды" end
	if (count >= 10 and count <= 19) or last == 0 or (last >= 5 and last <= 9) then return "секунд" end
end


-- GAME FUNCTIONS

function weaponPlayer()
	if getElementData(localPlayer, "status") == "playing" then
		if (not guiGetVisible(weaponsWindow)) then
			if(guiCheckBoxGetSelected(weaponShowIt)) then 
				showWeapons() 
			else 
				getWeapons()
			end
		end
	end
end

function playerReadyForPlaying(startedResource)
	if getElementData(localPlayer, "status") == "mapload" then
		if data["map"]["resource"] ~= -1 then
			local resource = getResourceFromName(data["map"]["resource"])
			if resource and (startedResource == resource) then
				triggerServerEvent("onPlayerReadyForMap", localPlayer)
			end
		end
	end
end

function allBlipsOnMap()
	for key, value in ipairs(getElementsByType("player")) do
		if not getElementData(value, "selecting") and (value ~= localPlayer) then
			local team = getElementData(value, "teamID")
			if not isElement(blips[value]) then 
				blips[value] = createBlipAttachedTo(value,0,2,data["teams"][team]["r"],data["teams"][team]["g"],data["teams"][team]["b"]) 
			else 
				setBlipColor(blips[value], data["teams"][team]["r"],data["teams"][team]["g"],data["teams"][team]["b"],255) end
		end
	end
end

function teamBlipsOnMap()
	local team = getElementData(localPlayer, "teamID")
	for key, value in ipairs(getElementsByType("player")) do
		if not getElementData(value, "selecting") and getElementData(value, "teamID") == team and (value ~= localPlayer) and (not isElement(blips[value])) then
			blips[value] = createBlipAttachedTo(value,0,2,data["teams"][team]["r"],data["teams"][team]["g"],data["teams"][team]["b"])
		else
			if isElement(blips[value]) and getElementData(value, "teamID") ~= team then 
				destroyElement(blips[value]) 
			end
		end
	end
end

function flashingBlip(flashBlip)
	if flashBlip and isElement(flashBlip) then
		if getBlipSize(flashBlip) == 3.0 then 
			local team = getElementData(localPlayer, "teamID")
			setBlipSize(flashBlip, 2.0)
			setBlipColor(flashBlip, data["teams"][team]["r"], data["teams"][team]["g"], data["teams"][team]["b"], 255)
		else
			setBlipSize(flashBlip, 3.0)
			setBlipColor(flashBlip, 0, 0, 255, 255)
		end
	end
end

function backToBounds(source)
	data["out"]["time"] = data["out"]["time"] - 1
	outString = "Вы умрёте через "..data["out"]["time"].." "..seconds(data["out"]["time"])
	if (not isElement(source) or data["out"]["time"] == 0) then
		removeEventHandler("onClientRender", root, drawOutBounds)
		if(isTimer(data["out"]["timer"])) then 
			killTimer(data["out"]["timer"])
		end
		if data["out"]["time"] == 0 then
			setElementHealth(localPlayer, 0)
			playSoundFrontEnd(45)
		end
	else
		playSoundFrontEnd(44)
	end
end

-- костыльно
function getWeapons()
	local weapons = {}
	
	local weaponFromItem = {
		[1] = {};
		[2] = {};
		[3] = {};
	}
	
	local ammoFromItem = {
		[1] = {};
		[2] = {};
		[3] = {};
	}
	
	for i=1,3 do
		for key,value in pairs(data["weapons"][i]) do
			table.insert(weaponFromItem[i], key)
			table.insert(ammoFromItem[i], value)
		end
	end
	
	for i=1,3 do 
		local x,y = guiGridListGetSelectedItem(weaponsSlot[i])
		if x ~= -1 then
			x = x + 1
			if weapons[weaponFromItem[i][x]] then weapons[weaponFromItem[i][x]] = weapons[weaponFromItem[i][x]] + ammoFromItem[i][x] else weapons[weaponFromItem[i][x]] = ammoFromItem[i][x] end
		end
	end
	
	if (data["main"]["status"] == "starting") or (data["main"]["status"] == "playing") then
		triggerServerEvent("giveWeapons", localPlayer, weapons)
	else
		outputChatBox("Вы выбрали оружие.")
	end
	
	if guiGetVisible(weaponsWindow) then showWeapons() end
end


-- CUSTOM EVENTS

function onRoundStop(winner)
	onRoundEnd()
	setSoundVolume(playSound("finish.mp3"), 0.6)
	if winner == -1 then
		winsString = "Ничья!"
		winsColor = data["teams"][3]["color"]
	else
		winsString = "Команда "..data["teams"][winner]["name"].." выиграла"
		winsColor = data["teams"][winner]["color"]
	end
	countString = "("..data["teams"][1]["name"]..") "..getElementData(data["teams"][1]["team"], "status").. ":"..getElementData(data["teams"][2]["team"], "status").." ("..data["teams"][2]["name"]..")"
	addEventHandler("onClientRender", root, drawWins)
	removeEventHandler("onClientRender", root, drawRoundTime)
	setTimer(function() 
	allBlipsOnMap()
	removeEventHandler("onClientRender", root, drawWins) end, 7000, 1)
end

function onPlayerMapLoading(res, id)
	data["map"]["resource"] = res
	data["main"]["status"] = "loading"
	loadingRoundString = "Waiting. Arena "..id
	addEventHandler("onClientRender", root, drawLoadingRound)
end

function onPlayerSkipMap()
	removeEventHandler("onClientRender", root, drawLoadingRound)
end

function onRoundRequestStarting(map)
	data["map"]["id"] = map 
	data["main"]["status"] = "starting"
	data["counter"]["count"] = data["counter"]["default"]
	data["counter"]["timer"] = setTimer(onRoundStarting, 1000, data["counter"]["count"])
	onRoundStarting()
	addEventHandler("onClientRender", root, drawArenaName) 
	removeEventHandler("onClientRender", root, drawLoadingRound)
end

function onRoundStarting(map)
	startingString = "Арена " .. data["map"]["id"] .. " запустится через " .. data["counter"]["count"] .. " " .. seconds(data["counter"]["count"])
	data["counter"]["count"] = data["counter"]["count"] - 1
end

function onRoundEnd()
	canMeChangeWeapons = true
	if data["main"]["pause"] then
		data["main"]["pause"] = false
		removeEventHandler("onClientRender", root, drawPause)
	end
	if data["main"]["status"] == "starting" then 
		removeEventHandler("onClientRender", root, drawArenaName) 
		if isTimer(data["counter"]["timer"]) then killTimer(data["counter"]["timer"]) end
	elseif data["main"]["status"] == "playing" then
		if isTimer(data["round"]["timer"]) then killTimer(data["round"]["timer"]) end
		removeEventHandler("onClientRender", root, drawRoundTime)
	elseif data["main"]["status"] == "loading" then
		removeEventHandler("onClientRender", root, drawLoadingRound)
	end
	if guiGetVisible(weaponsWindow) then showWeapons() end
	data["main"]["status"] = "lobby"
end

function onRoundPause()
	data["main"]["pause"] = not data["main"]["pause"]
	if data["main"]["pause"] then
		addEventHandler("onClientRender", root, drawPause)
	else
		removeEventHandler("onClientRender", root, drawPause)
	end
end

function onRoundPlaying()
	if not data["main"]["pause"] then
		data["round"]["time"] = data["round"]["time"] - 1
		if data["round"]["time"] == 0 then 
			killTimer(data["round"]["timer"])
			removeEventHandler("onClientRender", root, drawRoundTime)
		end
		roundTimeString = string.format("Time: %02d:%02d", data["round"]["time"] / 60, data["round"]["time"] % 60)
		for i=1,2 do teamStrings[i] = getTeamName(data["teams"][i]["team"])..": "..getElementData(data["teams"][i]["team"], "count").." / "..countPlayersInTeam(data["teams"][i]["team"]) end
	end
end

function onRoundStart(roundTime)
	setTime(12,0)
	setWeather(7)
	canMeChangeWeapons = true
	data["main"]["status"] = "playing"
	if roundTime then 
		data["round"]["time"] = roundTime 
	else 
		data["round"]["time"] = data["round"]["default"] 
		addEventHandler("onClientRender", root, drawRoundTime)
		removeEventHandler("onClientRender", root, drawArenaName)	
	end
	if isTimer(data["round"]["timer"]) then killTimer(data["round"]["timer"]) end
	data["round"]["timer"] = setTimer(onRoundPlaying, 1000, 0)
	teamBlipsOnMap()
	onRoundPlaying()
	weaponPlayer()
end

function onPlayerWarpToLobby(source)
	if (data["main"]["status"] == "playing") or (data["main"]["status"] == "starting") then teamBlipsOnMap() else allBlipsOnMap() end
end

function onPlayerReady()
	setAircraftMaxHeight(10000)
	setBlurLevel(0)
	setWeather(7)
	weaponsSlot = {}
	weaponsWindow = guiCreateWindow(screenWidth*0.23,screenHeight*0.05,649,223,"Оружие",false)
	weaponsSlot[1] = guiCreateGridList(15,31,200,135,false,weaponsWindow)
	guiGridListSetSelectionMode(weaponsSlot[1],0)
	weaponsSlot[2] = guiCreateGridList(222,31,200,136,false,weaponsWindow)
	guiGridListSetSelectionMode(weaponsSlot[2],0)
	weaponsSlot[3] = guiCreateGridList(429,31,200,138,false,weaponsWindow)
	guiGridListSetSelectionMode(weaponsSlot[3],0)
	weaponSelect = guiCreateButton(469,180,150,29,"Выбрать",false,weaponsWindow)
	weaponShowIt = guiCreateCheckBox (20,180, 250, 29, "Показывать в начале раунда?",true,false,weaponsWindow)
	for i=1,3 do
		guiGridListSetSortingEnabled(weaponsSlot[i], false)
		guiGridListAddColumn(weaponsSlot[i], "Weapon", 0.55)
		guiGridListAddColumn(weaponsSlot[i], "Ammo", 0.25)
	end
	guiSetVisible(weaponsWindow, false)
	bindKey("b", "down", "gun", "")
	bindKey("enter", "down", function() if guiGetVisible(weaponsWindow) then getWeapons() end end)
	
	addEventHandler("onClientGUIClick", weaponSelect, getWeapons, false)
	triggerServerEvent("onPlayerReady", localPlayer)
end

function onPlayerRequestClass()
	addEventHandler("onClientRender", root, drawClassName)
end

function onPlayerClassChange(classid)
	classNameString = getTeamName(data["teams"][classid]["team"])
	classColor = data["teams"][classid]["color"]
end

function onPlayerClassSelected(classid)
	removeEventHandler("onClientRender", root, drawClassName)
end

function onConfigUpdate(config)
	data = config
	for i=1,3 do
		guiGridListClear(weaponsSlot[i])
		for key,value in pairs(data["weapons"][i]) do
			local row = guiGridListAddRow(weaponsSlot[i])
			guiGridListSetItemText (weaponsSlot[i], row, 1, data["weaponNames"][key], false, false)
			guiGridListSetItemText (weaponsSlot[i], row, 2, tostring(value), false, false)
		end
	end
	guiCheckBoxSetSelected(weaponShowIt, true)
	for i=1,3 do
		local r,g,b = getTeamColor(data["teams"][i]["team"])
		data["teams"][i]["color"] = tocolor(r,g,b,255)
	end
	for key,value in pairs(data["hud"]) do showPlayerHudComponent(key, value) end
end

function showWeapons()
	if getElementData(localPlayer, "teamID") ~= 3 then
		if canMeChangeWeapons then
			cursorShow(not guiGetVisible(weaponsWindow))
			guiSetVisible(weaponsWindow, not guiGetVisible(weaponsWindow))
		else
			outputChatBox("Ты уже не можешь сменить пак!")
		end
	end
end

function toFlashBlip(playerName)
	setTimer(flashingBlip, 250, 20, blips[getPlayerFromName(playerName)])
end

function onPlayerBoundsEnter()
	if(isElement(source)) then
		if(isTimer(data["out"]["timer"])) then 
			removeEventHandler("onClientRender", root, drawOutBounds)
			killTimer(data["out"]["timer"])
		end
	end	
end

function onPlayerBoundsLeave()
	if(isElement(source)) then
		data["out"]["time"] = data["out"]["default"]
		backToBounds()
		if(not isTimer(data["out"]["timer"])) then
			data["out"]["timer"] = setTimer(backToBounds,1000,0,source)
		else
			killTimer(data["out"]["timer"])
			data["out"]["timer"] = setTimer(backToBounds,1000,0,source)
		end
		addEventHandler("onClientRender", root, drawOutBounds)
	end	
end


-- DRAWING FUNCTIONS

function drawClassName()
    dxDrawText(classNameString, 0,0, screenWidth-1, screenHeight+screenHeight*0.45+1, tocolor ( 0, 0, 0, 255 ), 1, "bankgothic", "center", "center")
    dxDrawText(classNameString, 0,0, screenWidth+1, screenHeight+screenHeight*0.45+1, tocolor ( 0, 0, 0, 255 ), 1, "bankgothic", "center", "center")
    dxDrawText(classNameString, 0,0, screenWidth-1, screenHeight+screenHeight*0.45-1, tocolor ( 0, 0, 0, 255 ), 1, "bankgothic", "center", "center")
    dxDrawText(classNameString, 0,0, screenWidth+1, screenHeight+screenHeight*0.45-1, tocolor ( 0, 0, 0, 255 ), 1, "bankgothic", "center", "center")
    dxDrawText(classNameString, 0,0, screenWidth, screenHeight+screenHeight*0.45, classColor, 1, "bankgothic", "center", "center")
end

function drawOutBounds()
    dxDrawText(outString, 0,0, screenWidth-screenWidth*0.01-1, screenHeight-screenHeight*0.03+1, tocolor ( 0, 0, 0, 255 ), 1, "bankgothic", "right", "bottom")
    dxDrawText(outString, 0,0, screenWidth-screenWidth*0.01+1, screenHeight-screenHeight*0.03+1, tocolor ( 0, 0, 0, 255 ), 1, "bankgothic", "right", "bottom")
    dxDrawText(outString, 0,0, screenWidth-screenWidth*0.01-1, screenHeight-screenHeight*0.03-1, tocolor ( 0, 0, 0, 255 ), 1, "bankgothic", "right", "bottom")
    dxDrawText(outString, 0,0, screenWidth-screenWidth*0.01+1, screenHeight-screenHeight*0.03-1, tocolor ( 0, 0, 0, 255 ), 1, "bankgothic", "right", "bottom")
    dxDrawText(outString, 0,0, screenWidth-screenWidth*0.01, screenHeight-screenHeight*0.03, tocolor ( 255, 255, 255, 255 ), 1, "bankgothic", "right", "bottom")
end

function drawArenaName()
    dxDrawText(startingString, 0,0, screenWidth-screenWidth*0.01-1, screenHeight-screenHeight*0.03+1, tocolor ( 0, 0, 0, 255 ), 1, "bankgothic", "right", "bottom")
    dxDrawText(startingString, 0,0, screenWidth-screenWidth*0.01+1, screenHeight-screenHeight*0.03+1, tocolor ( 0, 0, 0, 255 ), 1, "bankgothic", "right", "bottom")
    dxDrawText(startingString, 0,0, screenWidth-screenWidth*0.01-1, screenHeight-screenHeight*0.03-1, tocolor ( 0, 0, 0, 255 ), 1, "bankgothic", "right", "bottom")
    dxDrawText(startingString, 0,0, screenWidth-screenWidth*0.01+1, screenHeight-screenHeight*0.03-1, tocolor ( 0, 0, 0, 255 ), 1, "bankgothic", "right", "bottom")
    dxDrawText(startingString, 0,0, screenWidth-screenWidth*0.01, screenHeight-screenHeight*0.03, tocolor ( 255, 255, 255, 255 ), 1, "bankgothic", "right", "bottom")
end

function drawRoundTime()
	dxDrawRectangle(0, 0, screenWidth, screenHeight*0.02, tocolor(0,0,0,235))
	dxDrawText(roundTimeString, 0, 0, screenWidth, screenHeight, tocolor(255,255,255,255), 0.5, "bankgothic", "center", "top")
	dxDrawText(teamStrings[1], -screenWidth*0.2, 0, screenWidth, screenHeight, data["teams"][1]["color"], 0.5, "bankgothic", "center", "top")
	dxDrawText(teamStrings[2], screenWidth*0.2, 0, screenWidth, screenHeight, data["teams"][2]["color"], 0.5, "bankgothic", "center", "top")
end

function drawWins()
    dxDrawText(winsString, 0, 0, screenWidth, screenHeight-2, tocolor(0,0,0,255), 3, "sans", "center", "center")
    dxDrawText(winsString, 0, 0, screenWidth, screenHeight, winsColor, 3, "sans", "center", "center")
    dxDrawText(countString, 0, 0, screenWidth, screenHeight+75, tocolor(0,0,0,255), 3, "sans", "center", "center")
    dxDrawText(countString, 0, 0, screenWidth, screenHeight+77, tocolor(255,255,255,255), 3, "sans", "center", "center")
end

function drawPause()
	dxDrawRectangle(0, 0, screenWidth, screenHeight, tocolor(0,0,0,128))
    dxDrawText("Pause..", 0, 0, screenWidth, screenHeight-2, tocolor(0,0,0,255), 3, "sans", "center", "center")
    dxDrawText("Pause..", 0, 0, screenWidth, screenHeight, tocolor(255,255,255,255), 3, "sans", "center", "center")
end

function drawLoadingRound()
    dxDrawText(loadingRoundString, 0,0, screenWidth-screenWidth*0.01-1, screenHeight-screenHeight*0.03+1, tocolor ( 0, 0, 0, 255 ), 1, "bankgothic", "right", "bottom")
    dxDrawText(loadingRoundString, 0,0, screenWidth-screenWidth*0.01+1, screenHeight-screenHeight*0.03+1, tocolor ( 0, 0, 0, 255 ), 1, "bankgothic", "right", "bottom")
    dxDrawText(loadingRoundString, 0,0, screenWidth-screenWidth*0.01-1, screenHeight-screenHeight*0.03-1, tocolor ( 0, 0, 0, 255 ), 1, "bankgothic", "right", "bottom")
    dxDrawText(loadingRoundString, 0,0, screenWidth-screenWidth*0.01+1, screenHeight-screenHeight*0.03-1, tocolor ( 0, 0, 0, 255 ), 1, "bankgothic", "right", "bottom")
    dxDrawText(loadingRoundString, 0,0, screenWidth-screenWidth*0.01, screenHeight-screenHeight*0.03, tocolor ( 255, 255, 255, 255 ), 1, "bankgothic", "right", "bottom")
end


-- NATIVE EVENTS

function onPlayerShoot(weapon)
	if data["main"]["status"] == "playing" and weapon ~= 0 then canMeChangeWeapons = false end
end

function onPlayerDeath()
	if isElement(blips[source]) then 
		destroyElement(blips[source])
	end
end

function onPlayerExit()
	if isElement(blips[source]) then 
		destroyElement(blips[source])
	end
end

function onPlayerScreenRender()
	if getTickCount() >= fpsTime+1000 then
		setElementData(localPlayer, "fps", fps)
		fps = 0
		fpsTime = getTickCount()
	else
		fps = fps + 1
	end
end

-- CUSTOM EVENT HANDLERS
addEvent("onRoundStart", true)
addEvent("onRoundStop", true)
addEvent("onRoundEnd", true)
addEvent("onRoundRequestStarting", true)
addEvent("onRoundPause", true)
addEvent("onPlayerRequestClass", true)
addEvent("onPlayerClassChange", true)
addEvent("onPlayerClassSelected", true)
addEvent("onPlayerWarpToLobby", true)
addEvent("onPlayerMapLoading", true)
addEvent("onBoundsEnter", true)
addEvent("onBoundsLeave", true)
addEvent("onConfigUpdate", true)
addEvent("showWeapons", true)
addEvent("toFlashBlip", true)
addEvent("onPlayerSkipMap", true)
addEventHandler("onPlayerSkipMap", root, onPlayerSkipMap)
addEventHandler("onRoundStart", root, onRoundStart)
addEventHandler("onRoundStop", root, onRoundStop)
addEventHandler("onRoundEnd", root, onRoundEnd)
addEventHandler("onRoundRequestStarting", root, onRoundRequestStarting)
addEventHandler("onRoundPause", root, onRoundPause)
addEventHandler("onPlayerRequestClass", root, onPlayerRequestClass)
addEventHandler("onPlayerClassChange", root, onPlayerClassChange)
addEventHandler("onPlayerClassSelected", root, onPlayerClassSelected)
addEventHandler("onPlayerWarpToLobby", root, onPlayerWarpToLobby)
addEventHandler("onPlayerMapLoading", root, onPlayerMapLoading)
addEventHandler("onConfigUpdate", root, onConfigUpdate)
addEventHandler("showWeapons", localPlayer, showWeapons)
addEventHandler("toFlashBlip", root, toFlashBlip)
addEventHandler("onClientRender", root, onPlayerScreenRender)
addEventHandler("onBoundsEnter", root, onPlayerBoundsEnter)
addEventHandler("onBoundsLeave", root, onPlayerBoundsLeave)

-- NATIVE EVENT HANDLERS
addEventHandler("onClientPlayerWasted", root, onPlayerDeath)
addEventHandler("onClientPlayerQuit", root, onPlayerExit)
addEventHandler("onClientPlayerWeaponFire", localPlayer, onPlayerShoot)
addEventHandler("onClientResourceStart", getResourceRootElement(getThisResource()), onPlayerReady)
addEventHandler("onClientResourceStart", root, playerReadyForPlaying)

-- PLAYER COMMANDS
addCommandHandler("gun", showWeapons)